﻿#include<iostream>
#include<type_traits>

/*变量模版*/

//template<class T>
//constexpr T pi = T(3.1415926535897932385L); // 变量模板

//
//template<std::size_t N>
//constexpr std::size_t factorial = N * factorial<N - 1>;
//// 特化
//template<>
//constexpr std::size_t factorial<0> = 1;
//
//template< class T >
//constexpr bool is_const_v = std::is_const<T>::value;//这里也可以使用别名模版来实现
//
//template< class T >
//using is_const_v = std::is_const<T>::value;


/*泛型lambda*/


#include <iostream>
#include <vector>
#include <algorithm>
#include<functional>
//int main() {
//	// 另⼀个泛型Lambda⽰例 - 返回两个参数中较⼤的⼀个
//	//auto getMax = [](const auto& a, const auto& b) {
//	//	return a > b ? a : b;
//	//	};
//	//std::cout << "最大的整数: " << getMax(10, 20) << std::endl;
//	//std::cout << "最大的字符串: " << getMax(std::string("apple"),
//	//	std::string("banana")) << std::endl;
//
//
//	//auto func = [](auto&& x, auto& y) {
//	//	x += 97;
//	//	y += 97;
//	//	};
//	//int i = 0, j = 1;
//	//func(10, i);
//	//func(j, i);
//
//	//std::string s1("hello world");
//	//std::vector<std::string> v;
//	//auto f1 = [&v](auto&&... ts)
//	//	{
//	//		v.emplace_back(std::forward<decltype(ts)>(ts)...);
//	//	};
//	//f1(std::move(s1));
//	//f1("1111111");
//	//f1(10, 'y');
//
//
//
//	//std::vector<int> numbers = { 1, 2, 3, 4, 5 };
//	//// 使⽤表达式初始化捕获的变量
//	//auto p = std::make_unique<int>(10);
//	//auto lambda1 = [value = 5, ptr = std::move(p), &numbers]() {
//	//	std::cout << "捕获的值: " << value << std::endl;
//	//	std::cout << "捕获的智能指针值: " << *ptr << std::endl;
//	//	std::cout << "捕获的vector大小: " << numbers.size() << std::endl;
//	//	};
//	//lambda1();
//	//
//
//	//std::cout << p << std:: endl;
//
//
//
//
//	// 泛型 lambda，operator() 是⼀个拥有两个（模板）形参的模板
//	auto glambda = []<class T>(T a, auto&& b) { return a < b; };
//	// 泛型 lambda，operator() 是⼀个拥有⼀个形参包的模板
//	std::vector<std::string> v;
//	auto f2 = [&v]<typename... Args>(Args&&... ts)
//		{
//		v.emplace_back(std::forward<Args>(ts)...);
//	};
//
//
//}


/*尾置返回类型*/


// C++14 普通函数可以直接⽤auto做返回类型，⾃动推导返回类型
//int x = 1;
//auto f1() { return x; } // 返回类型是 int
//auto& f2() { return x; } // 返回类型是 int&
//auto f3(int x) { return x * 1.5; } // 返回类型是double
//
//// 报错，多返回语句需类型⼀致
//auto f4(int x) {
//	if (x > 0)
//		return 1.0; // double
//	else
//		return 2; // int → 错误：类型不⼀致

//}
//int x = 1;
//decltype(auto) f1() { return x; } // 返回类型是 int，同 decltype(x)
//decltype(auto) f2() { return (x); } // 返回类型是 int&，同 decltype((x))


//template<typename F, typename... Args>
//decltype(auto) call(F&& f, Args&&... args) 
//{
//	return std::forward<F>(f)(std::forward<Args>(args)...);
//	
//}



#include<bitset>
/*⼆进制字⾯量*/
//int main()
//{
//	const int FLAG_A = 0b0001; // 1
//	const int FLAG_B = 0b0010; // 2
//	const int FLAG_C = 0b0100; // 4
//	const int FLAG_D = 0b1000; // 8
//	int flags = FLAG_A | FLAG_C; // 0b0101
//
//	std::bitset<16> foo;
//	std::bitset<16> bar(0xfa2);
//	std::bitset<16> baz(std::string("0101111001"));
//
//	std::cout << "foo: " << foo << '\n';
//	std::cout << "bar: " << bar << '\n';
//	std::cout << "baz: " << baz << '\n';
//}

/*数字分隔符*/
//#include <iostream>
//
//int main() {
//    // 用单引号分隔，增强可读性，编译后实际就是 1'000'000
//    int million = 1'000'000;
//
//    std::cout << million << std::endl;  
//
//    return 0;
//}


/*聚合类*/


//struct Employee {
//	std::string name = "Unknown";
//	int id = -1;
//	double salary = 0.0;
//	
//	void add(int a,int b){}
//
//};
//
//int main() {
//	Employee e1 = { "xxx", 1, 1.1 };//98
//	Employee e2();//11
//	//14
//	Employee e2{ "John" }; // name="John", id=-1, salary=0.0
//	Employee e3{ "Alice", 123 }; // name="Alice", id=123, salary=0.0
//	Employee e4{}; // 值初始化，等同于e1 --11
//
//
//
//	struct Inner {
//		int a;
//		int b;
//	};
//	struct Outer {
//		Inner i;
//		int c;
//	};
//	Outer o1{ .i{1,2}, .c = 3 };
//	// 或
//	Outer o2{ .i = {.a = 1, .b = 2}, .c = 3 };
//
//}



/*exchange测试*/


//#include <iostream>
//#include <iterator>
//#include <utility>
//#include <vector>
//class stream
//{
//public :
//	using flags_type = int;
//public:
//	flags_type flags() const { return flags_; }
//	/// 以 newf 替换 flags_ 并返回旧值。
//	flags_type flags(flags_type newf) { return std::exchange(flags_, newf); }
//private:
//	flags_type flags_ = 0;
//};
//
//
//template<class T ,class U=T>
//std::vector<int>  Exchange(T obj, U&& New) {
//	return std::vector<int>();
//}
//int main()
//{
//	/*std::vector<int> v = { 10,20,30 };
//	std::vector<int> ret = Exchange(v, { 1, 2, 3, 4 });
//	for (auto e : v)
//		std::cout << e << " ";
//	std::cout << "\n";
//	for (auto e : ret)
//		std::cout << e << " ";
//	std::cout << "\n";*/
//
//
//
//	/*stream s;
//	std::cout << s.flags() << '\n';
//	std::cout << s.flags(12) << '\n';
//	std::cout << s.flags() << "\n\n";*/
//	
//	std::cout << "\n\n斐波那契数列: ";
//	for (int a{ 0 }, b{ 1 }; a < 100; a = std::exchange(b, a + b))
//		std::cout << a << ", ";
//	std::cout << "...\n";
//	return 0;
//}


/*make_unique测试*/

//#include<iostream>
//#include<vector>
//#include<typeinfo>
//using namespace std;
//int main() {
//
//	/*unique_ptr<vector<int>> upv1 = make_unique<vector<int>>();
//	unique_ptr<vector<int>> upv3 = make_unique<vector<int>>(vector<int>(10,1));
//	unique_ptr<vector<int>> upv4 = make_unique<vector<int>>(vector<int>{1,2,3});
//	unique_ptr<int> upv5 = make_unique<int>();
//	cout << *upv5.get() << endl;*/
//
//
//	unique_ptr<vector<int>[]> upv5 = make_unique_for_overwrite<vector<int>[]>(10);
//	(*upv5.get())[1];
//
//
//
//
//
//	return 0;
//}


/*integer_sequence*/
//#include <cstddef>
//#include <iostream>
//#include <tuple>
//#include <utility>
//template <typename T, T... ints>
//void print_sequence(int id, std::integer_sequence<T, ints...> int_seq)
//{
//	std::cout << id << "）大小为 " << int_seq.size() << " 的序列: ";
//	((std::cout << ints << ' '), ...);
//	std::cout << '\n';
//} 
//int main()
//{
//	print_sequence(1, std::integer_sequence<unsigned, 9, 2, 5, 1, 9, 1, 6>{});
//	print_sequence(2, std::make_integer_sequence<int, 12>{});
//	print_sequence(3, std::make_index_sequence<10>{});
//	print_sequence(4, std::index_sequence_for<std::ios, float, signed>{});
//	return 0;
//}


/*通过integer_sequence系列函数完成根据元组类型个数完成确定索引进行打印*/

// 实际应⽤ - 元组解包
//template<typename... Args, std::size_t... Indices>
//void print_tuple_impl(const std::tuple<Args...>& t,
//	std::index_sequence<Indices...>) {
//// 使⽤折叠表达式(C++17)打印元组元素
//		((std::cout << std::get<Indices>(t) << " "), ...);
//	std::cout << std::endl;
//} 
//
//template<typename... Args>
//void print_tuple(const std::tuple<Args...>& t) {
//	print_tuple_impl(t, std::index_sequence_for<Args...>());
//}
//
//
//
//int main() {
//	// 打印元组
//		auto t = std::make_tuple(10, 3.14, "Hello", 'A');
//	std::cout << "元组内容: ";
//	print_tuple(t);
//
//}

/*std::quoted介绍*/
//
//#include<iostream>
//#include<iomanip>
//#include<sstream>
//#include<string>
//using namespace std;
//int main() {
//
//	//输出时候：
//	
//	//string s = "hello";
//	//// 输出时用 quoted，会自动给 s 加上双引号
//	//cout << quoted(s) << endl;
//	
//
//	//输入时候：
//
//	//string inputStr;
//	////cout << "请输入一个带引号的字符串（例如 \"world\"）：";
//	////cin >> quoted(inputStr); // 从输入流中读取，自动去掉外层引号
//	//cin >> inputStr;
//	//cout << "你去掉引号后的字符串是：" << inputStr << endl;
//	//cout << "你去掉引号后的字符串是（使用quoted）：" << quoted(inputStr) << endl;
//
//
//	// 假设我们从某处读入了一个带转义的带引号字符串，或者要输出这样的字符串
//	//string text = R"("他说:"C++ 很强大！"" )"; // 原始带转义的形式
//	//string text = "他说:\n\"C++很强大！\"\""; // 原始带转义的形式
//	//// 输出时用 quoted，会自动处理转义
//	//cout << "输出带转义的 quoted 字符串：" << text<< endl;
//	//cout << "输出带转义的 quoted 字符串：" << quoted(text) << endl;
//
//	//// 也可以反过来：从带引号+转义的字符串读入
//	//string readBack;
//	//istringstream iss(text);
//	//cout << text << endl;
//	//iss >> quoted(readBack);  // 读取时会自动解析转义
//
//	//cout << "读取并解析后得到的字符串：" << readBack << endl;
//	//string s("\n");
//	//cout << s.size();
//	
//	return 0;
//}


//#include <iostream>
//#include <sstream>
//#include <iomanip>
//#include <string>
//
//struct Config {
//	std::string username;
//	std::string password;
//	std::string server;
//	int id;
//};
//// 序列化配置到字符串
//std::string serializeConfig(const Config& config) {
//	std::ostringstream oss;
//	oss << std::quoted(config.username) 
//		<< std::quoted(config.password)
//		<< std::quoted(config.server)
//		<< config.id;
//	return oss.str();
//}
//// 从字符串反序列化配置
//Config deserializeConfig(const std::string & str) {
//	std::istringstream iss(str);
//	Config config;
//	iss >> std::quoted(config.username)
//		>> std::quoted(config.password)
//		>> std::quoted(config.server)
//		>> config.id;
//	return config;
//} 
//int main() {
//	Config original{ "admin hello", "pssword@.com", "example.com", 1 };
//	// 序列化
//	std::string serialized = serializeConfig(original);
//	std::cout << "Serialized: " << serialized << "\n";
//	// 反序列化
//	Config restored = deserializeConfig(serialized);
//	std::cout << "Restored values:\n"
//		<< "Username: " << restored.username << "\n"
//		<< "Password: " << restored.password << "\n"
//		<< "Server: " << restored.server << "\n"
//		<< "Id: " << restored.id << "\n";
//	return 0;
//}




/*字面量后缀*/

// C++98就有的字⾯量后缀
// 整形和浮点数的字⾯量后缀
//auto a = 10; // int
//auto b = 10u; // unsigned int
//auto c = 10l; // long
//auto d = 10ul; // unsigned long
//auto e = 10ll; // long long
//auto f = 10ull; // unsigned long long
//auto g = 3.14; // double
//auto h = 3.14f; // float
//auto i = 3.14l; // long double
//
//
//
//#include<string>
//#include<string_view>
//#include<iostream>
//#include<thread>
//#include<chrono>
//using namespace std::literals;
//std::string operator "" _s(const char* str, size_t len) {
//	return std::string(str, len);
//} 
//
//std::string_view operator "" _sv(const char* str, size_t len) {
//	return std::string_view(str, len);
//}
//
//constexpr long double operator "" _km(unsigned long long int x) {
//	return x * 1000.0; // 将公⾥转换为⽶
//}
//int main() {
//	auto s0 = "halo";//这里如果不加后缀默认是char const *类型
//	std::cout<<typeid(s0).name();
//	auto s1 = "halo"_s;
//	auto s2 = "halo"_sv;
//	auto d = 5_km;
//
//	
//	std::this_thread::sleep_for(std::chrono::seconds(500));
//	// 时间字⾯量
//	std::this_thread::sleep_for(500ms);
//
//}


/*shared_mutex与shared_timed_mutex测试*/


#include <iostream>
#include <shared_mutex>
#include <thread>
#include <vector>
#include <mutex>
#include <syncstream>
#include<chrono>
#define MY_COUT std::osyncstream(std::cout)
std::shared_mutex mtx;  // 共享互斥锁
int shared_data = 0;    // 共享数据
using namespace std::literals;
// 读线程（多个线程可以同时读）
void reader(int id) {
    std::shared_lock<std::shared_mutex> lock(mtx);  // 共享锁（读锁）
    std::this_thread::sleep_for(2s);
    MY_COUT << "Reader " << id << " sees data: " << shared_data << std::endl;
    // 锁自动释放（离开作用域）
}

// 写线程（只有两个个线程可以写）
void writer(int id, int new_value)  {
    std::unique_lock<std::shared_mutex> lock(mtx);  // 独占锁（写锁）
    shared_data = new_value;
    MY_COUT << "Writer " << id << " sets data to: " << shared_data << std::endl;
    std::this_thread::sleep_for(1s);

    // 锁自动释放（离开作用域）
}

int main() {
    std::vector<std::thread> threads;

    // 启动 3 个读线程
    for (int i = 0; i < 3; ++i) {
        threads.emplace_back(reader, i);
    }
     

    MY_COUT << "主线程休眠3s" << std::endl;
    std::this_thread::sleep_for(3s);

    // 启动 2 个写线程
    threads.emplace_back(writer, 1, 42);
    threads.emplace_back(writer, 2, 42);


    // 启动 4个读线程
    for (int i = 3; i < 7; ++i) {
        threads.emplace_back(reader, i);
    }

    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }

    return 0;
}
